package cn.angis.flow.service;

import cn.angis.common.constant.Constant;
import cn.angis.common.model.PageModel;
import cn.angis.common.model.PageResult;
import cn.angis.db.service.BaseService;
import cn.angis.flow.access.WfConstants;
import cn.angis.flow.dtomapper.HistoryOrderStruct;
import cn.angis.flow.mapper.HistorderMapper;
import cn.angis.flow.model.Historder;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import org.noear.solon.annotation.Inject;
import org.noear.solon.aspect.annotation.Service;
import org.noear.solon.data.annotation.Tran;
import org.snaker.engine.SnakerEngine;
import org.snaker.engine.access.Page;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.entity.HistoryOrder;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.Task;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
* 历史流程实例表服务
* @author angis.cn
* @Date 2023-05-11
*/
@Service
public class HistorderService extends BaseService<HistorderMapper, Historder> {

    @Inject
    private SnakerEngine snakerEngine;

    public PageResult<Historder> flowPage(Historder entity, PageModel pageModel) {
        Page<HistoryOrder> page = new Page<>();
        page.setPageNo((int)pageModel.getCurrent());
        page.setPageSize(pageModel.getSize());
        QueryFilter queryFilter = new QueryFilter();
        if(entity.getOrderState()!=null) {
            queryFilter.setState(entity.getOrderState());
        }
        if(StrUtil.isNotBlank(entity.getDisplayName())) {
            queryFilter.setDisplayName(entity.getDisplayName());
        }
        if(StrUtil.isNotBlank(entity.getCode())) {
            queryFilter.setNames(new String[]{entity.getCode()});
        }
        queryFilter.setOperators(new String[]{StpUtil.getSession().get(Constant.SESSION_LOGIN_NAME).toString()});
        List<HistoryOrder> historyOrders = snakerEngine.query().getHistoryOrders(page, queryFilter);
        historyOrders.forEach(historyOrder -> {
            handleOrderStatus(historyOrder);
        });
        PageResult<Historder> pageResult = new PageResult<>();
        pageResult.setCurrent(page.getPageNo());
        pageResult.setPages(page.getTotalPages());
        pageResult.setSize(page.getPageSize());
        pageResult.setTotal(page.getTotalCount());
        pageResult.setRecords(HistoryOrderStruct.INSTANCE.toHistorderList(historyOrders));
        return pageResult;
    }

    /**
     * 处理流程实例状态-优先使用变量中的状态
     * @param historyOrder
     * @return
     */
    private HistoryOrder handleOrderStatus(HistoryOrder historyOrder) {
        if(historyOrder!=null && historyOrder.getVariableMap().get(WfConstants.ORDER_STATE_KEY)!=null) {
            historyOrder.setOrderState(Integer.valueOf(historyOrder.getVariableMap().get(WfConstants.ORDER_STATE_KEY).toString()));
        }
        return historyOrder;
    }

    @Tran
    public void startAndExecute(Historder entity) {
        Process process = snakerEngine.process().getProcessById(entity.getProcessId());
        entity.getArgs().put(WfConstants.INSTANCE_URL, process.getInstanceUrl());
        // 设置业务ID
        entity.getArgs().put(SnakerEngine.ID, UUID.randomUUID().toString().replaceAll("-",""));
        // 创建流程实例用户名
        entity.getArgs().put(WfConstants.ORDER_USER_NAME_KEY, StpUtil.getSession().get(Constant.SESSION_LOGIN_NAME));
        // 创建流程实例姓名
        entity.getArgs().put(WfConstants.ORDER_USER_REAL_NAME_KEY, StpUtil.getSession().get(Constant.SESSION_USER_NAME));
        Order order = snakerEngine.startInstanceById(entity.getProcessId(), StpUtil.getSession().get(Constant.SESSION_USER_ID).toString(), entity.getArgs());
        List<Task> tasks = snakerEngine.query().getActiveTasks(new QueryFilter().setOrderId(order.getId()));
        List<Task> newTasks = new ArrayList<Task>();
        if (tasks != null && tasks.size() > 0) {
            Task task = tasks.get(0);
            newTasks.addAll(snakerEngine.executeTask(task.getId(), SnakerEngine.AUTO, entity.getArgs()));
        }
    }
}